package cn.getech.data.development.service.impl;

import cn.getech.data.development.dto.JobCronDto;
import cn.getech.data.development.dto.JobNodeConfigDto;
import cn.getech.data.development.entity.BdpModelTask;
import cn.getech.data.development.entity.JobNodeConf;
import cn.getech.data.development.entity.JobNodeTable;
import cn.getech.data.development.mapper.*;
import cn.getech.data.development.model.res.jobInfo.JobDataRes;
import cn.getech.data.development.model.res.procinfo.ProcInfoListRes;
import cn.getech.data.development.model.vo.JobDataVo;
import cn.getech.data.development.service.JobNodeConfService;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.system.center.service.SysRoleService;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 任务信息配置表 服务实现类
 * </p>
 *
 * @author zenith
 * @since 2018-08-27
 */
@Service
public class JobNodeConfServiceImpl extends ServiceImpl<JobNodeConfMapper, JobNodeConf> implements JobNodeConfService {

    @Autowired
    private ConfConnectMapper confConnectMapper;
    @Autowired
    private BdpModelTaskMapper bdpModelTaskMapper;

    @Autowired
    private JobNodeConfMapper jobNodeConfMapper;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private ProcInfoMapper procInfoMapper;

    @Autowired
    private JobNodeTableMapper jobNodeTableMapper;

	@Override
	public void upsertKVByJobNodeId(List<JobNodeConf> jobNodeConfList) {
		this.baseMapper.upsertKVByJobNodeId(jobNodeConfList);
	}

    @Override
    public JobNodeConfigDto getJobNodeConf(List<JobNodeConf> jobNodeConfs) {
        if (jobNodeConfs == null)
            return null;
        Map<String,Object> map=new HashMap<>();
        for (JobNodeConf conf:jobNodeConfs
        ) {
            if(conf.getKey()!=null&&conf.getKey().equals("input_connect_id") && StringUtils.isNotEmpty(conf.getValue())){
                if(confConnectMapper.selectById(conf.getValue())!=null){
                    /**查询数据源名称*/
                    map.put("input_connect_name",confConnectMapper.selectById(conf.getValue()).getName());
                    /**查询数据源节点*/
                    map.put("input_connect_type",confConnectMapper.selectById(conf.getValue()).getTypeId());
                }
                else{
                    throw new RRException("数据配置中的数据源已不存在，请重新配置");
                }
            }
            if(conf.getKey()!=null&&conf.getKey().equals("output_connect_id") && StringUtils.isNotEmpty(conf.getValue())){
                if(confConnectMapper.selectById(conf.getValue())!=null){
                    map.put("output_connect_name",confConnectMapper.selectById(conf.getValue()).getName());
                }else{
                    throw new RRException("数据配置中的数据源已不存在，请重新配置");
                }
            }
            map.put(conf.getKey(),conf.getValue());
        }
        return JobNodeConfigDto.mapToJobNodeConfigDto(map);
    }

    @Override
    public JobNodeConf selectKVByJobNodeIdAndKey(Integer id, String key,Integer jobType) {
        return this.baseMapper.selectKVByJobNodeIdAndKey(id,key,jobType);
    }

    @Override
    public void insertJobNodeConfig(JobCronDto jobCronDto) {
        try {
            String sysEndTime = jobCronDto.getSysEndTime();
            String sysStartTime = jobCronDto.getSysStartTime();
            Long workMenuId = jobCronDto.getWorkMenuId();
            Double sysDurTime = jobCronDto.getSysDurTime();


            List<JobNodeConf> lists = new ArrayList<>();
            JobNodeConf jobNodeConf = new JobNodeConf();
            jobNodeConf.setKey("isOpenTime");
            jobNodeConf.setJobNodeId(workMenuId.intValue());
            jobNodeConf.setJobType(1);
            jobNodeConf.setValue("1");
            lists.add(jobNodeConf);

            JobNodeConf jobNodeConf1 = new JobNodeConf();
            jobNodeConf1.setKey("sysDurTime");
            jobNodeConf1.setJobNodeId(workMenuId.intValue());
            jobNodeConf1.setJobType(1);
            jobNodeConf1.setValue(sysDurTime.toString());
            lists.add(jobNodeConf1);

            //平移时间
            String newStartTimes = nextTimes(sysStartTime,sysDurTime);
            JobNodeConf jobNodeConf2 = new JobNodeConf();
            jobNodeConf2.setKey("sysStartTime");
            jobNodeConf2.setJobNodeId(workMenuId.intValue());
            jobNodeConf2.setJobType(1);
            jobNodeConf2.setValue(newStartTimes);
            lists.add(jobNodeConf2);

            //平移时间
            String newEndTimes = nextTimes(sysEndTime,sysDurTime);
            JobNodeConf jobNodeConf3 = new JobNodeConf();
            jobNodeConf3.setKey("sysEndTime");
            jobNodeConf3.setJobNodeId(workMenuId.intValue());
            jobNodeConf3.setJobType(1);
            jobNodeConf3.setValue(newEndTimes);
            lists.add(jobNodeConf3);

            //修改配置
            this.upsertKVByJobNodeId(lists);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private String nextTimes(String sysTime, Double sysDurTime) {
        Double dur = sysDurTime * 60 * 60 * 1000;
        long ddd = DateUtil.parseDateTime(sysTime).getTime() + dur.longValue();
        return DateUtil.formatDateTime(DateUtil.date(ddd));
    }

    @Override
    public void saveOrUpdateModelTask(BdpModelTask bdpModelTask) {
	    if(null != bdpModelTask){
            BdpModelTask modelTask = bdpModelTaskMapper.selectOne(new QueryWrapper<BdpModelTask>()
                    .eq("task_id", bdpModelTask.getTaskId()).eq("model_id", bdpModelTask.getModelId()));
            if(null== modelTask){
                bdpModelTaskMapper.insert(bdpModelTask);
            }

        }
    }

    @Override
    public Page<JobDataRes> getJobDataPage(JobDataVo jobDataVo) {
        Page<JobDataRes> jobDataResPage = new Page<>(jobDataVo.getPage(),jobDataVo.getPageSize());
        //获取项目列表
        Map<String,Object> params = new HashMap<>();
        Integer tenantId = ShiroUtils.getTenantId();
        Long userId = ShiroUtils.getUserId();
        if(sysRoleService.isSuperAdmin(userId)){
            params.put("userId", null);
        }else{
            params.put("userId", userId);
        }
        params.put("currentUserId",userId);
        params.put("tenantId", tenantId);//租户id
        //如果不是租户管理员，值查询关联这个项目的用户
        List<ProcInfoListRes> proList = procInfoMapper.selectProcOwer(params);
        if (proList.size() == 0) return jobDataResPage;

        List<Integer> proIdList = proList.stream().map(ProcInfoListRes::getId).collect(Collectors.toList());
        jobDataVo.setProIdList(proIdList);
        jobDataVo.setCurrentUserId(userId);

        List<JobDataRes> list = jobNodeConfMapper.getJobDataPage(jobDataResPage,jobDataVo);
        jobDataResPage.setRecords(list);
        return jobDataResPage;
    }

    @Override
    public void insertJobNodeTable(JobNodeTable jobNodeTable) {
//        jobNodeTableMapper.insert(jobNodeTable);

        //判断是否已经被关联
        //获取被关联的任务列表
        JobDataVo jobDataVo = new JobDataVo();
        jobDataVo.setPage(1);
        jobDataVo.setPageSize(1000);
        jobDataVo.setTableId(jobNodeTable.getTableId());
        jobDataVo.setTableName(jobNodeTable.getTableName());
        List<JobDataRes> jobDataList = getJobDataPage(jobDataVo).getRecords();

        if (jobDataList != null && jobDataList.size() != 0){
            //获取jobNodeId列表
            List<Integer> jobNodeIdList = jobDataList.stream().map(JobDataRes::getJobNodeId).collect(Collectors.toList());
            //判断是否存在
            for (Integer jobNodeId : jobNodeTable.getJobNodeIdList()) {
                if (jobNodeIdList.contains(jobNodeId)) {
                    String jobNodeName = jobDataList.stream().filter(j -> j.getJobNodeId().equals(jobNodeId)).map(j -> j.getJobName()).collect(Collectors.joining(","));
                    throw new RRException("该表 " + jobNodeTable.getTableName() + " 已关联 " + jobNodeName + " 任务，请重新关联");
                }
            }
        }


        jobNodeTableMapper.batchInsert(jobNodeTable);
    }

    @Override
    public List<Map<String, Object>> getJobDataCreateBy(JobDataVo jobDataVo) {
        //获取项目列表
        Map<String,Object> params = new HashMap<>();
        Integer tenantId = ShiroUtils.getTenantId();
        Long userId = ShiroUtils.getUserId();
        if(sysRoleService.isSuperAdmin(userId)){
            params.put("userId", null);
        }else{
            params.put("userId", userId);
        }
        params.put("currentUserId",userId);
        params.put("tenantId", tenantId);//租户id
        //如果不是租户管理员，值查询关联这个项目的用户
        List<ProcInfoListRes> proList = procInfoMapper.selectProcOwer(params);
        if (proList.size() == 0) return new ArrayList<>();

        List<Integer> proIdList = proList.stream().map(ProcInfoListRes::getId).collect(Collectors.toList());
        jobDataVo.setProIdList(proIdList);
        List<Map<String, Object>> list = jobNodeConfMapper.getJobDataCreateBy(jobDataVo);
        return list;
    }
}
